{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 向量化"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([0., 1., 0., 1., 0., 1., 0., 1., 0., 1.])\n"
     ]
    }
   ],
   "source": [
    "import torch\n",
    "N_CLASSES = 10\n",
    "label = \"1 3 5 7 9\"\n",
    "target = torch.zeros(N_CLASSES)\n",
    "for cls in label.split():\n",
    "    target[int(cls)] = 1\n",
    "print (target)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# DataLoader"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "from torch.utils.data import DataLoader, Dataset"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 继承Dataset类，并至少实现这三个函数\n",
    "# DataLoader + Dataset实现数据的bactch管理\n",
    "\n",
    "class TestDataset(Dataset):\n",
    "    def __init__(self, df, transform=None):\n",
    "        '''构造函数，为数据提供必要的信息。'''\n",
    "        self.df = df   # 数据信息\n",
    "        self.transform = transform  # 数据预处理\n",
    "        \n",
    "    def __len__(self):\n",
    "        '''数据的长度，通过就是df的长度，有时候也会写成其它值。比如只用部分数据，或数据用好几遍'''\n",
    "        return len(self.df)\n",
    "\n",
    "    def __getitem__(self, idx):\n",
    "        '''定义取数据的方法。给数据的index，返回第index个数据。'''\n",
    "        file_name = self.df['id'].values[idx]\n",
    "#         file_path = f'../input/imet-2020-fgvc7/test/{file_name}.png'\n",
    "#         image = cv2.imread(file_path)\n",
    "#         image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n",
    "        \n",
    "#         if self.transform:\n",
    "#             augmented = self.transform(image=image)\n",
    "#             image = augmented['image']\n",
    "        \n",
    "        return file_name"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['5ce6c26d0102df314251bf8b64b4511c']\n",
      "['c4eb75aa15a1d33de92892b23cc6a91a']\n"
     ]
    }
   ],
   "source": [
    "import pandas as pd\n",
    "\n",
    "df = pd.read_csv(\"file/2064.csv\")\n",
    "test_dataset = TestDataset(df)\n",
    "# shuffle: 乱序取出\n",
    "# batch_size: 即使一次只取一个数据，也是以数组的形式给出\n",
    "test_loader = DataLoader(test_dataset, batch_size=1, shuffle=False)\n",
    "for data in test_loader:\n",
    "    print (data)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# resnet18"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'models' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-8-f3a357cfa69f>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mmodel\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mmodels\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mresnet18\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mpretrained\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;32mFalse\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m      2\u001b[0m \u001b[0mmodel\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mavgpool\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mnn\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mAdaptiveAvgPool2d\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m      3\u001b[0m \u001b[0mmodel\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mfc\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mnn\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mLinear\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mmodel\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mfc\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0min_features\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mN_CLASSES\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m      4\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m      5\u001b[0m \u001b[0mweights_path\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;34m'../input/imet-2020-pytorch-resnet18-starter/fold0_best_score.pth'\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;31mNameError\u001b[0m: name 'models' is not defined"
     ]
    }
   ],
   "source": [
    "model = models.resnet18(pretrained=False)\n",
    "model.avgpool = nn.AdaptiveAvgPool2d(1)\n",
    "model.fc = nn.Linear(model.fc.in_features, N_CLASSES)\n",
    "\n",
    "weights_path = '../input/imet-2020-pytorch-resnet18-starter/fold0_best_score.pth'\n",
    "model.load_state_dict(torch.load(weights_path))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'model' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-9-b68b6e8fd0c3>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[0;32m      1\u001b[0m \u001b[0mdevice\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mtorch\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mdevice\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m'cuda'\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mtorch\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mcuda\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mis_available\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;32melse\u001b[0m \u001b[1;34m'cpu'\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 2\u001b[1;33m \u001b[0mmodel\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mto\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mdevice\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;31mNameError\u001b[0m: name 'model' is not defined"
     ]
    }
   ],
   "source": [
    "device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\n",
    "model.to(device) "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# create net"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "def create_net(net_cls, pretrained: bool):\n",
    "    if pretrained:\n",
    "        net = net_cls()\n",
    "        model_name = net_cls.__name__\n",
    "        weights_path = f'../input/{model_name}/{model_name}.pth'\n",
    "        net.load_state_dict(torch.load(weights_path))\n",
    "    else:\n",
    "        net = net_cls(pretrained=pretrained)\n",
    "    return net"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'nn' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-3-053b09fd09a2>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[1;32mclass\u001b[0m \u001b[0mResNet\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mnn\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mModule\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m      2\u001b[0m     def __init__(self, num_classes,\n\u001b[0;32m      3\u001b[0m                  pretrained=False, net_cls=M.resnet50, dropout=False):\n\u001b[0;32m      4\u001b[0m         \u001b[0msuper\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m__init__\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m      5\u001b[0m         \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mnet\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mcreate_net\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mnet_cls\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mpretrained\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mpretrained\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;31mNameError\u001b[0m: name 'nn' is not defined"
     ]
    }
   ],
   "source": [
    "class ResNet(nn.Module):\n",
    "    def __init__(self, num_classes,\n",
    "                 pretrained=False, net_cls=M.resnet50, dropout=False):\n",
    "        super().__init__()\n",
    "        self.net = create_net(net_cls, pretrained=pretrained)\n",
    "        self.net.avgpool = AvgPool()\n",
    "        if dropout:\n",
    "            self.net.fc = nn.Sequential(\n",
    "                nn.Dropout(),\n",
    "                nn.Linear(self.net.fc.in_features, num_classes),\n",
    "            )\n",
    "        else:\n",
    "            self.net.fc = nn.Linear(self.net.fc.in_features, num_classes)\n",
    "\n",
    "    def fresh_params(self):\n",
    "        return self.net.fc.parameters()\n",
    "\n",
    "    def forward(self, x):\n",
    "        return self.net(x)\n",
    "\n",
    "\n",
    "class DenseNet(nn.Module):\n",
    "    def __init__(self, num_classes,\n",
    "                 pretrained=False, net_cls=M.densenet121):\n",
    "        super().__init__()\n",
    "        self.net = create_net(net_cls, pretrained=pretrained)\n",
    "        self.avg_pool = AvgPool()\n",
    "        self.net.classifier = nn.Linear(\n",
    "            self.net.classifier.in_features, num_classes)\n",
    "\n",
    "    def fresh_params(self):\n",
    "        return self.net.classifier.parameters()\n",
    "\n",
    "    def forward(self, x):\n",
    "        out = self.net.features(x)\n",
    "        out = F.relu(out, inplace=True)\n",
    "        out = self.avg_pool(out).view(out.size(0), -1)\n",
    "        out = self.net.classifier(out)\n",
    "        return out"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([0.0474, 0.1192, 0.2689, 0.5000, 0.7311, 0.8808, 0.9526])"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import torch\n",
    "\n",
    "x = torch.Tensor([-3,-2,-1, 0, 1,2,3])\n",
    "torch.sigmoid(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
